package md.frolov.bible.model;

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;

import md.frolov.bible.Constants;

public class Archive implements IViewLabelProvider, IStructure{
	private static Archive instance;
	private Map<String,Category> categories = new HashMap<String,Category>();
	private Map<String,Module> modules = new HashMap<String,Module>();

	
	public static Archive getInstance(){
		if(instance==null){
			instance = new Archive();
		}
		return instance;
	}

	
	
	public Archive(){
	
	}

	/* (non-Javadoc)
	 * @see md.frolov.bible.model.IStructure#getChildren(java.lang.Object)
	 */
	@Override
	public Object[] getChildren() {
		return categories.values().toArray();
	}

	/* (non-Javadoc)
	 * @see md.frolov.bible.model.IStructure#getParent(java.lang.Object)
	 */
	@Override
	public Object getParent() {
		return null;
	}



	/* (non-Javadoc)
	 * @see md.frolov.bible.model.IStructure#hasChildren(java.lang.Object)
	 */
	@Override
	public boolean hasChildren() {
		if(categories.values().size()>0) return true;
		return false;
	}
	
	public Module getModuleByID(String id){
		Module ret = modules.get(id);
		if (ret==null) {
			ret = new Module(id);
			modules.put(id, ret);
		}
		
		return ret;
	}

	public void addModuleStructure(Module module) {
		Category cat = getCategoryByID(module.getCategory());
		Language lang = cat.getLanguageById(module.getLanguage());
		lang.addModule(module);
	}

	public Category getCategoryByID(String categoryId){
		Category cat = categories.get(categoryId);
		if(cat==null){
			cat = new Category(categoryId);
			categories.put(categoryId, cat);
		}
		return cat;
	}
	
	public String getText(){
		return "main";
	}

	public IStructure resolveUrl(String url, Class clazz){
		if(!IStructure.class.isAssignableFrom(clazz)) return null;
		
		IStructure result = resolveUrl(url);
		while(!(result instanceof Archive)){
			if(result.getClass().equals(clazz)) break;
			result = (IStructure) result.getParent();
		}
		return result;
	}

	public Chapter resolveUrl(String url) {
		Matcher m = Constants.urlPattern.matcher(url);
		String moduleId;
		String bookId;
		String chapterId;
		Module module;
		Book book;
		Chapter chapter;
		
		if(!m.matches()) return null; //TODO Exception?
		
		moduleId = m.group(1);
		module = Archive.getInstance().getModuleByID(moduleId);
		
		bookId = m.group(2);
		if(bookId == null) {
			book = module.getFirstBook();
			chapter = book.getFirstChapter();
			return chapter;
		}
		book = module.getBookByLocalId(bookId);
		
		chapterId = m.group(3);
		if(chapterId == null){
			chapter = book.getFirstChapter();
			return chapter;
		}
		chapter = book.getChapterByLocalId(chapterId);
		
		return chapter;
		
	}



	@Override
	public String getId() {
		return ".";
	}

	public Module getModuleByFile(File file) {
		Collection<Module> ms = modules.values();
		for (Iterator<Module> iterator = ms.iterator(); iterator.hasNext();) {
			Module m = iterator.next();
			if(m.getFile().equals(file)) return m;
		}
		return null;
	}



	public Collection<Module> getModules() {
		return modules.values();
	}
	
	public String getUrlForStringLocation(String yok){
		Collection<Module> modules = getModules();
		for (Iterator<Module> iterator = modules.iterator(); iterator.hasNext();) {
			Module module = iterator.next();
			if(module.matches(yok))
				return module.getUrlForStringLocation(yok);
		}
		return null;
	}
}
